<?php

@session_start();
/***********************************************************************************************/
/*                        __  __   _        _    ____    _    _   _    _                       */
/*                       |  \/  | | |      / \  / ___|  / \  | \ | |  / \                      */
/*                       | |\/| | | |     / _ \| |  _  / _ \ |  \| | / _ \                     */
/*                       | |  | |_| |___ / ___ \ |_| |/ ___ \| |\  |/ ___ \                    */
/*                       |_|  |_(_)_____/_/   \ \____/_/   \ \_| \_/_/   \ \                   */
/*                                             \_\          \_\           \_\                  */
/*                                                                                             */
/*                                                                                             */
/*   Copyright (C) 2008 Mathieu Lagana <mathieu.lagana{at}gmail.com>                           */
/*                                                                                             */
/*   This program is free software; you can redistribute it and/or                             */
/*   modify it under the terms of the GNU General Public License                               */
/*   as published by the Free Software Foundation; either version 2                            */
/*   of the License, or (at your option) any later version.                                    */
/*                                                                                             */
/*   This program is distributed in the hope that it will be useful,                           */
/*   but WITHOUT ANY WARRANTY; without even the implied warranty of                            */
/*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                             */
/*   GNU General Public License for more details.                                              */
/*                                                                                             */
/*   You should have received a copy of the GNU General Public License                         */
/*   along with this program; if not, write to the Free Software                               */
/*   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.           */
/*                                                                                             */
/*                           ########                                                          */
/*                         ##;;;;;;;;##                                                        */
/*                       #;;;;;;;;;;;;;;#                                                      */
/*                        #;; PHP ;;;;;;;####                                                  */
/*                      ##;;;;;;;;;;;;;;;;;;;#                                                 */
/*                     #;;; development ;;;;;;##                                               */
/*                    ########;;;;;;#;;;;;;;;;;#                                               */
/*          ########;#;;;;;;;;;;;;;;;;;;;;;;;;;;#                                              */
/*         #;;; Mathieu LAGANA ;;;;;;;;###########                                             */
/*         #;;;;;;;;;;;;;;;;;;###;;####                                                        */
/*        # ###;;;#;###;;;;###   ##                                                            */
/*     ###;##;########;;;;##########      ######                                               */
/*    #;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#  ###;;;;;;######## #                                     */
/*   #;;;;;; 2008 ;;;;;;;;;;;;;;;;;;;##;;;;;;;;;;;;;;;;;#;###                                  */
/*     #####;;;;;#;;;; calendar making class ;;;;;;;;;;;;;;;;#                                 */
/*          ##### ##########;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#                                 */
/*                        # oCalendarPicker ;#####;;;;;;;;###                                  */
/*                     ###;;;;;;;;;;;;;;;;;;#     ########                                     */
/*                   #;;;;;;;;;;;###########                                                   */
/*            #######;;; v 1.0 ;;;;;;;;;;;;;#######                                            */
/*          ##;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#                                           */
/*         #;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#                                            */
/*          ######################################                                             */
/*                                                                                             */
/*                                                                                             */
/***********************************************************************************************/

/**
 * Calendar making class
 * 
 * Can display calendar or datePicker
 * Can reload page or fill textfield
 * 
 * Easy localisation
 * Css standalone file for easy integration
 * 
 * 
 * @author Mathieu LAGANA
 * @copyright Mathieu LAGANA <mathieu.lagana{at}gmail.com>
 * 
 * @version 1.0 20081002
 *
 */
class oCalendarPicker{
	
	/**
	 * Default params for display calendar and reload page
	 *
	 * @var array $aDefaultParams
	 */
	private $aDefaultParams=array(
	   "sIconPath"     =>  "./img/calendar.png",
	   "iAction"       =>  0,   //0=>reloadCurrentPage with get param sDate, 1=>fill field sFieldName
	   "sFieldName"    =>  "",
	   "iStyle"        =>  0,   //0=>display calendar, 1=>display div on icon click
	   "aMonthNames"   =>  array("January","February","March","April","May","June","July","August","September","October","November","December"),
	   "aDaysNames"    =>  array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"), 
	   "sDateFormat"   =>  "Ymd" //Date format for output
	);
	
	/**
	 * Params used by class
	 *
	 * @var array $aCurrentParams
	 */
	private $aCurrentParams=array();
	
	/**
	 * Name for container div for calendar. Need to be unique in final document.
	 *
	 * @var string $sNameInstance
	 */
	private $sNameInstance;
	
	/**
	 * Timestamp for current date
	 *
	 * @var int $iDate
	 */
	private $iDate;
	
	/**
	 * Days number for current month
	 *
	 * @var int $iNbDays
	 */
	private $iNbDays;
	
	/**
	 * Display for first time or Update exsiting
	 * 0=>display, 1=update
	 * 
	 * @var int $iUpdate
	 */
	private $iUpdate;

	/**
	 * string path of page for update
	 *
	 * @var string $sPath
	 */
	private $sPath;
	
		
	/**
	 * Display calendar or datePicker
	 *
	 * @param string $sNameInstance Name for container div for calendar. Need to be unique in final document.
	 * @param string $sDate Current date of instance
	 * @param array $aParams Option for generation
	 * @param int $iUpdate Display for first time or Update exsiting 0=>display, 1=update
	 * @param string $sPath path of page for update
	 */
	function __construct($sNameInstance,$sDate=null, $aParams=array(),$iUpdate=0,$sPath=null){

		//Set current date	
		if (is_null($sDate)){
		    $sDate=date("Ymd");
		}
		$this->iDate=strtotime($sDate);
		
		//Set options
		$_SESSION['calendar_aParams'][$sNameInstance]=$aParams;
		$this->iUpdate=$iUpdate;
		$this->sPath=$sPath;
		$this->sNameInstance=$sNameInstance;
		$this->aCurrentParams=array_merge($this->aDefaultParams,$aParams);
		if ((int)$this->aCurrentParams['iAction']===1 && empty($this->aCurrentParams['sFieldName'])){
		    echo <<<eos
	<script type="text/javascript">
        alert("You must specifie text field ID in aParams array");
	</script>
eos;

		    exit;
		}
		$this->iNbDays=date("t",$this->iDate);
		//send output
		$this->display();
	}
	
	/**
	 * Build links for each event type
	 *
	 * @param string $sType update or reload or fill
	 * @param string $sFrom link or select
	 * @param int $iYear Nb years to add at current date
	 * @param int $iMonth Nb month to add at current date
	 * @param int $iDay Nb days to add at current date
	 * @param int $iDate target timestamp
	 * @return string
	 */
	function setEvent($sType="update",$sFrom="link", $iYear=null, $iMonth=null, $iDay=null, $iDate=null){
	    //set date value
	    if (!is_null($iMonth)||!is_null($iYear)||!is_null($iDay)){
	        $iDate=date("Ymd",mktime(0,0,0,date("m",$this->iDate)+$iMonth,date("d",$this->iDate)+$iDay,date("Y",$this->iDate)+$iYear));
	        $sDate="'".$iDate."'";
	    }elseif (!is_null($iDate)){
	        $sDate="'".$iDate."'";
	    }else {
	        $sDate='this.value';
	    }
	    
	    //set event
	    if ($sFrom==="link"){
	        $sEvent='onclick="';
	    }elseif ($sFrom==="select"){
	        $sEvent='onchange="';
	    }
	    
	    //set final link
	    $sPage=(is_null($this->sPath))?$_SERVER['PHP_SELF']:$this->sPath;
	    if($sType==="update"){
	        return $sEvent.="calendarUpdate('".$this->sNameInstance."','$sPage',".$sDate.");\"";
	    }elseif($sType==="reload"){
	        return $sEvent."calendarReload('http://".$_SERVER['SERVER_NAME'].$sPage."?sDate=".str_replace("'","",$sDate)."');\"";
	    }elseif($sType==="fill"){
	    	$style=$this->aCurrentParams['iStyle']===1?"none":"block";
	    	$sDate=date($this->aCurrentParams['sDateFormat'],strtotime($iDate));
	        return "onclick=\"document.getElementById('{$this->aCurrentParams['sFieldName']}').value='".$sDate."';document.getElementById('{$this->sNameInstance}').style.display='$style';calendarUpdate('".$this->sNameInstance."','$sPage',".$iDate.");\"";
	    }
	}
	
	/**
	 * function display
	 * echo final output
	 */
	function display(){
	    $iMonth=date("n",$this->iDate)-1;
	    $iYear=date("Y", $this->iDate);
	    $sToDisplay="";

	    //only if first display
	    if ($this->iUpdate===0){
	        $sStyleContainer="";
	        if ((int)$this->aCurrentParams['iStyle']===1){
	            $sStyleContainer=' style="display:none;position:absolute;z-index:2000;"';
	            $sToDisplay=<<<eos
	           <img src="{$this->aCurrentParams['sIconPath']}" onclick="document.getElementById('$this->sNameInstance').style.display='block';" alt="calendar"/>         
eos;

            }
            $sToDisplay.=<<<eos
        <div id="{$this->sNameInstance}" class="calendarContainer" $sStyleContainer>
eos;

        }

        //Display header
        $sToDisplay.=<<<eos
  <div class="calendarHeader">
  	<div class="calendarPrev" {$this->setEvent("update","link",-1)}>&lt;&lt;</div>
    <div class="calendarPrev" {$this->setEvent("update","link",null,-1)}>&lt;</div>
    <div class="calendarNext" {$this->setEvent("update","link",+1)}>&gt;&gt;</div>
    <div class="calendarNext" {$this->setEvent("update","link",null,+1)}>&gt;</div>
    {$this->aCurrentParams['aMonthNames'][$iMonth]} $iYear
  </div>
eos;

        //Display Select fields
        $sToDisplay.=<<<eos
  <div class="calendarChoice">
	<select name="YearSelect" style="float:right"  class="calendarChoiceSelect" {$this->setEvent("update","select")}>
eos;
        
        for($i=-5;$i<6;$i++){
            $year=($iYear+$i);
            $selected=((int)date("Y",$this->iDate)===(int)$year)?'selected="selected"':"";
            $val=$year.date("m",$this->iDate).date("d",$this->iDate);
            $sToDisplay.=<<<eos
            
            <option value="$val" $selected>$year</option>
eos;
        }
        $sToDisplay.="</select>";
       
        $sToDisplay.=<<<eos
        <select name="monthSelect"  class="calendarChoiceSelect" {$this->setEvent("update","select")}>
eos;

        foreach ($this->aCurrentParams['aMonthNames'] as $k=>$v){
             
            $day=(date("d",$this->iDate)>date("t",mktime(0,0,0,(int)substr("0".($k+1),0,2),1,$iYear)))?date("t",mktime(0,0,0,(int)substr("0".($k+1),0,2),1,$iYear)):date("d",$this->iDate);
            $selected=((int)date("m",$this->iDate)===(int)(substr("0".($k+1),-2,2)))?'selected="selected"':"";
            $val=$iYear.substr("0".($k+1),-2,2).$day;
            $sToDisplay.=<<<eos
            
            <option value="$val" $selected>$v</option>
eos;
        }
        $sToDisplay.=<<<eos
        </select>
    </div>
    
eos;

        //Display Calendar
        $sToDisplay.=<<<eos
        <div>
    <table cellspacing="1" class="calendarDisplay">
        <tr class="calendarNameDays">
eos;

        foreach ($this->aCurrentParams['aDaysNames'] as $v){
            $sToDisplay.="<td style=\"width:14%\">".substr($v,0,1)."</td>";
        }
        $sToDisplay.="</tr>";
        
        //Display days
        $sToDisplay.="<tr>";
        $FirstDayOfMonth=date("N",strtotime(date("Ym",$this->iDate)."01"));
        $LastDayOfMonth=date("N",strtotime(date("Ym",$this->iDate).$this->iNbDays));
        $FirstDayTodisplay=1-$FirstDayOfMonth;
        $LastDayOfMonth=7-$LastDayOfMonth;
        $p=1;
        for($i=$FirstDayTodisplay;$i<($this->iNbDays+$LastDayOfMonth);$i++){
            if($p===8){
                $sToDisplay.="</tr><tr>";
                $p=1;
            }
            $sType=($this->aCurrentParams['iAction']===0)?"reload":"fill";
            $iDate=strtotime(date("Ym",$this->iDate)."01");
            $currentDisplayingDate=mktime(0,0,0,date("m",$iDate),date("d",$iDate)+$i,date("Y",$iDate));
            $linkDate=($this->aCurrentParams['sDateFormat']===1)?date($this->aCurrentParams['sDateFormat'],$currentDisplayingDate):date("Ymd",$currentDisplayingDate);
            $displayDate=date("d",$currentDisplayingDate);
            $class=(date("m",$currentDisplayingDate)===date("m",$this->iDate))?"calendarNumDaysEnable":"calendarNumDaysDisable";
            $class=(date("Ymd",$currentDisplayingDate)===date("Ymd",$this->iDate))?"calendarToday":$class;
            $link=($class==="calendarNumDaysEnable" || $class==="calendarToday")? $this->setEvent($sType,"link",null,null,null,$linkDate):"";
            $sToDisplay.=<<<eos
            <td class="$class" $link >$displayDate</td>
eos;

            $p++;
        }
        $sToDisplay.="</tr>";
        
        //display Today
            $sType=($this->aCurrentParams['iAction']===0)?"reload":"fill";
            $iDate=strtotime(date("Ymd"));
            $currentDisplayingDate=mktime(0,0,0,date("m",$iDate),date("d",$iDate),date("Y",$iDate));
            $linkDate=($this->aCurrentParams['sDateFormat']===1)?date($this->aCurrentParams['sDateFormat'],$currentDisplayingDate):date("Ymd",$currentDisplayingDate);
            $displayDate=date($this->aCurrentParams['sDateFormat'],$currentDisplayingDate);
            $class="calendarNumDaysEnable";
            $link=$this->setEvent($sType,"link",null,null,null,$linkDate);
        
        $sToDisplay.=<<<eos
        <tr>
        	<td>&nbsp;</td>
            <td colspan="5" class="$class" $link >$displayDate</td>
            
eos;

        if ((int)$this->aCurrentParams['iStyle']===1){
        	$sToDisplay.=<<<eos
        	<td><font style="color:#FF0000;cursor:pointer;font-family:arial;font-weight:bold" onclick="document.getElementById('{$this->sNameInstance}').style.display='none'">X</font></td>
        </tr>
eos;

        	}else{
        	$sToDisplay.=<<<eos
        	<td>&nbsp;</td>
        </tr>
eos;
        	}
        
        $sToDisplay.="</table>
  </div>";
        
        if ($this->iUpdate===0){
            $sToDisplay.="</div><br/>";
        }
        echo $sToDisplay;
	}
}
?>